home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
comm
/
tcp
/
Amster.lha
/
Amster_Install
/
Source
/
navigator.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-07-31
|
14KB
|
462 lines
/*
** Amster - Navigator
** by Jacob Laursen <laursen@myself.com>
**
** (work in progress!)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <proto/dos.h>
#include <proto/socket.h>
#include <proto/utility.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/tcp.h>
#include <bsdsocket/socketbasetags.h>
#include <error.h>
#include <time.h>
#include <MUI/NListview_mcc.h>
#include "include/config.h"
#include "include/gui.h"
#include "include/info.h"
#include "include/mui.h"
#include "include/navigator.h"
#include "include/prefs.h"
#include "include/share.h"
#include "include/protos.h"
#include "amster_Cat.h"
#define NAPIGATOR_REQ "GET /servers.php?version=108 HTTP/1.0\r\n\r\n"
/* Global variables */
BOOL ServerListChanged = FALSE;
/* Private prototypes */
void LoadServerList(struct NavigatorData *data);
void SaveServerList(struct NavigatorData *data);
void MarkServerOnline(struct NavigatorData *data, char *server);
MUIF ServerListDisplay(REG(a2) char **array, REG(a1) struct ServerEntry *entry);
MUIF ServerListCompare(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct NList_CompareMessage *ncm);
MUIF ServerListDestruct(REG(a2) APTR pool, REG(a1) struct ServerEntry *entry);
MUIF ServerString(REG(a0) struct Hook *hook, REG(a1) APTR *contents);
BOOL GetNapigatorList(struct NavigatorData *data);
BOOL get_response(long sockfd, char *buf, int max);
void UpdateFromNapigator(struct NavigatorData *data, char *list);
MUIF NavigatorDispatch(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
{
struct NavigatorData *data;
struct ServerEntry *entry;
char *buf;
switch (msg->MethodID) {
case OM_NEW:
return(NavigatorNew(cl, obj, (APTR)msg));
case NAVI_CONNECT:
data = INST_DATA(cl, obj);
if (gui_onlinestate > OFFLINE) nap_logout();
get(data->ST_Server, MUIA_String_Contents, &buf);
if (gui_onlinestate < CONNECTING) {
nap_login_fromlist(buf);
}
return NULL;
case NAVI_GETSERVER:
data = INST_DATA(cl, obj);
DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry);
if (entry) {
set(data->ST_Server, MUIA_String_Contents, entry->Name);
set(data->ST_Comment, MUIA_String_Contents, entry->Comment);
}
return NULL;
case NAVI_ADDSERVER:
{
BOOL selected = FALSE;
data = INST_DATA(cl, obj);
DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry);
if (entry) selected = TRUE; /* One entry is already selected */
if (entry = malloc(sizeof(struct ServerEntry))) {
entry->LastOnline = 0;
if (selected) {
/* We clear the fields instead of dublicating selected entry */
entry->Name = strdup(MSG_NAVIGATOR_NEW);
entry->Comment = strdup("");
}
else {
get(data->ST_Server, MUIA_String_Contents, &buf);
entry->Name = strdup(buf);
get(data->ST_Comment, MUIA_String_Contents, &buf);
entry->Comment = strdup(buf);
}
DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted);
set(data->LV_Server, MUIA_NList_First, MUIV_NList_Active_Bottom);
/* DoMethod(data->LV_Server, MUIM_NList_Jump, MUIV_NList_Jump_Active);*/
ServerListChanged = TRUE;
}
}
return NULL;
case NAVI_REMOVESERVER:
data = INST_DATA(cl, obj);
DoMethod(data->LV_Server, MUIM_NList_Remove, MUIV_NList_Remove_Active);
ServerListChanged = TRUE;
return NULL;
case NAVI_REDRAWSERVER:
{
struct ServerEntry *entry;
APTR *contents = (APTR)(((muimsg)msg)->arg1);
data = INST_DATA(cl, obj);
DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry);
if (entry) {
if (*(contents+1) == 0) entry->Name = strdup(*contents);
else entry->Comment = strdup(*contents);
DoMethod(data->LV_Server, MUIM_NList_Redraw, MUIV_NList_Redraw_Active);
ServerListChanged = TRUE;
}
return NULL;
}
case NAVI_LOAD:
data = INST_DATA(cl, obj);
LoadServerList(data);
return NULL;
case NAVI_SAVE:
data = INST_DATA(cl, obj);
SaveServerList(data);
return NULL;
case NAVI_MARKSERVER:
data = INST_DATA(cl, obj);
MarkServerOnline(data, (char *)(((muimsg)msg)->arg1));
return NULL;
}
return(DoSuperMethodA(cl, obj, msg));
}
ULONG NavigatorNew(struct IClass *cl, Object *obj, struct opSet *msg)
{
static const struct Hook ServerListDispHook = { {NULL, NULL}, &ServerListDisplay, NULL, NULL };
static const struct Hook ServerListCompHook = { {NULL, NULL}, &ServerListCompare, NULL, NULL };
static const struct Hook ServerListDestHook = { {NULL, NULL}, &ServerListDestruct, NULL, NULL };
static const struct Hook ServerStringHook = { {NULL, NULL}, &ServerString, NULL, NULL };
struct NavigatorData *data;
Object *LV_Server, *ST_Server, *ST_Comment;
Object *BT_ConnectConnect, *BT_ConnectAdd, *BT_ConnectRemove;
if (obj = (Object *)DoSuperNew(cl, obj,
MUIA_HelpNode, "navi",
MUIA_Window_Title, MSG_NAVIGATOR_TITLE,
MUIA_Window_ID, MAKE_ID('N','A','V','I'),
WindowContents, VGroup,
Child, LV_Server = NListviewObject,
MUIA_NList_Input, TRUE,
MUIA_NListview_NList, NListObject,
InputListFrame,
MUIA_NList_ListBackground, MUII_ListBack,
MUIA_NList_TitleBackground, MUII_ListBack,
MUIA_NList_Title, TRUE,
MUIA_NList_Format, "BAR,BAR,",
MUIA_NList_DisplayHook, &ServerListDispHook,
MUIA_NList_CompareHook2, &ServerListCompHook,
MUIA_NList_DestructHook, &ServerListDestHook,
End,
End,
Child, ColGroup(2),
Child, Label2(MSG_NAVIGATOR_SERVER),
Child, ST_Server = StringObject,
MUIA_HorizWeight, 400,
StringFrame,
End,
Child, Label2(MSG_NAVIGATOR_COMMENT),
Child, ST_Comment = StringObject,
MUIA_HorizWeight, 400,
StringFrame,
End,
End,
Child, RectangleObject,
MUIA_FixHeight, 8,
MUIA_Rectangle_HBar, TRUE,
End,
Child, HGroup,
Child, BT_ConnectConnect = SimpleButton(MSG_NAVIGATOR_CONNECT_GAD),
Child, BT_ConnectRemove = SimpleButton(MSG_NAVIGATOR_REMOVE_GAD),
Child, BT_ConnectAdd = SimpleButton(MSG_NAVIGATOR_ADD_GAD),
End,
End,
TAG_MORE, msg->ops_AttrList))
{
data = INST_DATA(cl, obj);
data->LV_Server = LV_Server;
data->ST_Server = ST_Server;
data->ST_Comment = ST_Comment;
DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, obj, 3, MUIM_Set, MUIA_Window_Open, FALSE);
DoMethod(LV_Server, MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, LV_Server, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both);
DoMethod(LV_Server, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, LV_Server, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2);
DoMethod(LV_Server, MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, LV_Server, 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue);
DoMethod(LV_Server, MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, LV_Server, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue);
DoMethod(BT_ConnectConnect, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_CONNECT);
DoMethod(BT_ConnectRemove, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_REMOVESERVER);
DoMethod(BT_ConnectAdd, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_ADDSERVER);
DoMethod(LV_Server, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, obj, 1, NAVI_CONNECT);
LoadServerList(data);
DoMethod(LV_Server, MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, obj, 1, NAVI_GETSERVER);
set(ST_Server, MUIA_String_AttachedList, LV_Server);
DoMethod(ST_Server, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, ST_Server, 4, MUIM_CallHook, &ServerStringHook, MUIV_TriggerValue, 0);
DoMethod(ST_Comment, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, ST_Server, 4, MUIM_CallHook, &ServerStringHook, MUIV_TriggerValue, 1);
return((ULONG)obj);
}
return(0);
}
void LoadServerList(struct NavigatorData *data)
{
BPTR fh;
char buf[1024];
int line = 0;
struct ServerEntry *entry;
LONG argarray[] = { NULL, NULL, NULL };
UBYTE *argstr = "HOST/A,LASTUSED/A/N,COMMENT/K";
struct RDArgs *rdargs;
if (fh = Open("PROGDIR:Amster.servers", MODE_OLDFILE)) {
while (FGets(fh, buf, sizeof(buf))) {
line++;
if (rdargs = AllocDosObject(DOS_RDARGS, NULL)) {
rdargs->RDA_Buffer = NULL;
rdargs->RDA_Source.CS_Buffer = buf;
rdargs->RDA_Source.CS_Length = strlen(buf);
argarray[2] = 0;
if (ReadArgs(argstr, argarray, rdargs)) {
if (entry = malloc(sizeof(struct ServerEntry))) {
entry->Name = strdup((char *)argarray[0]);
entry->LastOnline = *((long *)argarray[1]);
if (argarray[2]) entry->Comment = strdup((char *)argarray[2]);
else entry->Comment = strdup("");
entry->Ping = -1;
DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted);
}
}
else gui_debugf((char *)MSG_PARSE_ERROR, "PROGDIR:Amster.servers", line);
FreeDosObject(DOS_RDARGS, rdargs);
}
}
Close(fh);
DoMethod(data->LV_Server, MUIM_NList_Sort);
}
}
void SaveServerList(struct NavigatorData *data)
{
struct ServerEntry *entry;
BPTR fh;
char buf[1024], *tmp;
int i;
fh = Open("PROGDIR:Amster.servers", MODE_NEWFILE);
if (!fh) return;
for (i=0; ; i++) {
DoMethod(data->LV_Server, MUIM_NList_GetEntry, i, &entry);
if (!entry) break;
if (entry->Comment) {
if (entry->Comment[0] != '\0') {
tmp = strrep(entry->Comment, "\"", "*\"");
sprintf(buf, "%s %ld COMMENT \"%s\"\n", entry->Name, entry->LastOnline, tmp);
free(tmp);
}
else sprintf(buf, "%s %ld\n", entry->Name, entry->LastOnline);
}
else sprintf(buf, "%s %ld\n", entry->Name, entry->LastOnline);
Write(fh, buf, strlen(buf)); /* Should be buffered, check FWrite */
}
Close(fh);
ServerListChanged = FALSE;
}
void MarkServerOnline(struct NavigatorData *data, char *server)
{
struct ServerEntry *entry=0;
struct DateStamp *ds, *rds;
int i;
BOOL new = FALSE;
for (i=0; ; i++) {
DoMethod(data->LV_Server, MUIM_NList_GetEntry, i, &entry);
if (!entry) break;
if (strcmp(server, entry->Name) == 0) break;
}
if (!entry) { /* Server not already on list */
if (prf->ServerList < 2) return;
if (entry = malloc(sizeof(struct ServerEntry))) {
entry->Name = strdup(server);
entry->LastOnline = 0; /* In case we don't succeed later on... */
entry->Comment = strdup("");
entry->Ping = -1;
new = TRUE;
}
}
if (ds = malloc(sizeof(struct DateStamp))) {
memset(ds, 0, sizeof(struct DateStamp));
if (rds = DateStamp(ds)) {
entry->LastOnline = rds->ds_Days*24*60*60 + rds->ds_Minute*60 + rds->ds_Tick/50;
if (new)
DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted);
else
DoMethod(data->LV_Server, MUIM_NList_Redraw, i);
ServerListChanged = TRUE;
}
free(ds);
}
}
MUIF ServerListDisplay(REG(a2) char **array, REG(a1) struct ServerEntry *entry)
{
struct DateTime dt;
static char buf[LEN_DATSTRING*2+6], buf2[20];
char datestring[LEN_DATSTRING], timestring[LEN_DATSTRING];
if (entry) {
*array++ = entry->Name;
if (entry->LastOnline == 0) *array++ = "\33r-";
else {
dt.dat_Stamp.ds_Days = (entry->LastOnline)/(60*60*24);
dt.dat_Stamp.ds_Minute = ((entry->LastOnline)%(60*60*24))/60;
dt.dat_Stamp.ds_Tick = ((entry->LastOnline)%60)*TICKS_PER_SECOND;
dt.dat_Format = FORMAT_DOS;
dt.dat_Flags = DTF_SUBST;
dt.dat_StrDay = NULL;
dt.dat_StrDate = datestring;
dt.dat_StrTime = timestring;
if (DateToStr(&dt)) {
sprintf(buf, "\33r%s %s", datestring, timestring);
*array++ = buf;
}
else *array++ = "\33r-";
}
*array++ = entry->Comment;
if (entry->Ping >= 0) {
sprintf(buf2, "%ld", entry->Ping);
*array = buf2;
}
else *array = "-";
}
else {
*array++ = (char *)MSG_NAVIGATOR_LIST_SERVER;
*array++ = (char *)MSG_NAVIGATOR_LIST_LASTONLINE;
*array++ = (char *)MSG_NAVIGATOR_LIST_COMMENT;
*array = (char *)MSG_NAVIGATOR_LIST_PING;
}
return 0;
}
MUIF ServerListCompare(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct NList_CompareMessage *ncm)
{
struct ServerEntry *entry1 = ncm->entry1;
struct ServerEntry *entry2 = ncm->entry2;
LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask;
LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask;
ULONG result = 0;
if (ncm->sort_type == MUIV_NList_SortType_None) return (0);
if (col1 == 0) {
if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
result = (LONG) stricmp(entry2->Name, entry1->Name);
else
result = (LONG) stricmp(entry1->Name, entry2->Name);
}
else if (col1 == 1) {
if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
result = entry2->LastOnline - entry1->LastOnline;
else
result = entry1->LastOnline - entry2->LastOnline;
}
else if (col1 == 2) {
if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
result = (LONG) stricmp(entry2->Comment, entry1->Comment);
else
result = (LONG) stricmp(entry1->Comment, entry2->Comment);
}
else if (col1 == 3) {
if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
result = entry2->Ping - entry1->Ping;
else
result = entry1->Ping - entry2->Ping;
}
if ((result != 0) || (col1 == col2)) return (result);
if (col2 == 0) {
if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
result = (LONG) stricmp(entry2->Name, entry1->Name);
else
result = (LONG) stricmp(entry1->Name, entry2->Name);
}
else if (col2 == 1) {
if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
result = entry2->LastOnline - entry1->LastOnline;
else
result = entry1->LastOnline - entry2->LastOnline;
}
else if (col2 == 2) {
if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
result = (LONG) stricmp(entry2->Comment, entry1->Comment);
else
result = (LONG) stricmp(entry1->Comment, entry2->Comment);
}
else if (col2 == 3) {
if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
result = entry2->Ping - entry1->Ping;
else
result = entry1->Ping - entry2->Ping;
}
return (result);
}
MUIF ServerListDestruct(REG(a2) APTR pool, REG(a1) struct ServerEntry *entry)
{
free(entry);
return 0;
}
MUIF ServerString(REG(a0) struct Hook *hook, REG(a1) APTR *contents)
{
DoMethod(gui->WI_Navigator, NAVI_REDRAWSERVER, contents);
return 0;
}